%{
/*
 * sr_scan.l: 
 * Clunix, cezanne@clunix.com, 2005.3
 *
 * Copyright (c) 2005 by Clunix Inc. All Rights Reserved.
 */

#include "config.h"

#include "sr.h"
#include "sr_parser.h"

#define MAX_BUF		1024

void asr_input(yyscan_t, char *, int *, int);

/* Have input call the following function. */
#undef  YY_INPUT
#define YY_INPUT(buf,result,max_size) \
		asr_input(yyscanner, (char *)buf, &result, max_size)
#define YY_NO_INPUT

%}

%option reentrant
%option bison-bridge
%option never-interactive
%option nounput
%option prefix="srp"
%option noyyalloc noyyrealloc noyyfree

%x sc_str
%x comment

%%
	char	buf[MAX_BUF];
	char	*buf_ptr = buf;

\/\*		BEGIN(comment);
<comment>\*\/	BEGIN(INITIAL);
<comment>.|\n

\"		buf_ptr = buf; *buf = '\0'; BEGIN(sc_str);

\{		return LeftBrace;
\}		return RightBrace;
;		return Semicolon;
\*		return Esterik;
&		return Ampersand;
\<		return LeftAngle;
\>		return RightAngle;
\{\{		return LeftDBrace;
\}\}		return RightDBrace;

[_[:alpha:]]+[_[:alnum:]]* {
			yylval->s_value = ecm_strdup(yytext);
			return Identifier;
		}
[^\n\r[:blank:]\*&\<\>\[\]\{\}\";]+	{
			yylval->s_value = ecm_strdup(yytext);
			return String;
		}
[\n\r[:blank:]]*
.		return Error;

<<EOF>>		return ENDOFBUF;

<sc_str>\"	{
			BEGIN(INITIAL);
			buf_ptr = '\0';
			yylval->s_value = ecm_strdup(buf);
			return String;
		}

<sc_str>\\[0-7]{1,3} {
			/* octal escape sequence */
			int	result;
			ecm_sscanf(yytext + 1, "%o", &result);
			if (result > 0xff)
				;
			*buf_ptr++ = result;
		}

<sc_str>\\[0-9]+	{
			/* generate error */
		}

<sc_str>\\n	*buf_ptr++ = '\n';
<sc_str>\\t	*buf_ptr++ = '\t';
<sc_str>\\r	*buf_ptr++ = '\r';
<sc_str>\\b	*buf_ptr++ = '\b';
<sc_str>\\f	*buf_ptr++ = '\f';
<sc_str>\\\\	*buf_ptr++ = '\\';
<sc_str>\\\"	*buf_ptr++ = '"';
<sc_str>\\[ ]	*buf_ptr++ = ' ';
<sc_str>\\(.|\n|\r\n)	

<sc_str>[^\\\"]+	ecm_strcpy(buf_ptr, yytext); buf_ptr += yyleng;

%%

int
yywrap(yyscan_t yyscanner)
{
	return 1;
}

void *
yyalloc(yy_size_t bytes, void *yyscanner)
{
	return ecm_malloc(bytes);
}

void *
yyrealloc(void *ptr, yy_size_t bytes, void *yyscanner)
{
	return ecm_realloc(ptr, bytes);
}

void
yyfree(void *ptr, void *yyscanner)
{
	ecm_free(ptr);
}
